module basemul(
  input clk,
  input rst,
  
  input valid_i,
  input flush,

  input mulw,
  input [1:0] mul_signed,
  input [63:0] src1,
  input [63:0] src2,
  
  output reg ready,
  output reg valid_o,
  output [63:0] res_hi,
  output [63:0] res_lo
);
  reg [128:0] res;
  reg [127:0] multiplicand;
  reg [63:0] multiplier;
  reg [6:0] cnt;
  reg res_sign;
  reg res_w;
  always @(posedge clk) begin
    if(rst|flush) begin   
      multiplicand    <= 128'b0;
      multiplier      <= 64'b0;
      valid_o <= 1'b0;
      ready <= 1'b1;
      res_sign <= 1'b0;
      res <= 129'b0;
      cnt <= 7'b0;
      res_w <= 1'b0;
    end else begin 
      valid_o <= 1'b0;
      res <= 129'b0;
      if(ready&valid_i) begin
        res_sign <= ^mul_signed;
        ready <= 1'b0;
        res_w <= mulw;
        if(mulw) begin
          if(mul_signed[1]&src1[31]) multiplicand  <= {96'b0,{(~src1[31:0])+32'b1}}; 
          else multiplicand <= {96'b0,src1[31:0]}; 
          if(mul_signed[0]&src2[31]) multiplier    <= {32'b0,{(~src2[31:0])+32'b1}}; 
          else multiplier   <= {32'b0,src2[31:0]};
          cnt <= 7'd32;
        end else begin
          if(mul_signed[1]&src1[63]) multiplicand  <= {64'b0,(~src1)+64'b1}; 
          else multiplicand <= {64'b0,src1}; 
          if(mul_signed[0]&src2[63]) multiplier    <= {(~src2)+64'b1}; 
          else multiplier   <= src2; 
          cnt <= 7'd64;
        end
      end else if(ready == 1'b0) begin
        if(multiplier[0]) res <= res + multiplicand;
        else res <= res;
        multiplier <= multiplier >> 1;
        multiplicand <= multiplicand << 1;
        cnt <= cnt - 7'd1;
        if(cnt == 7'd1) begin
          ready <= 1'b1;
          valid_o <= 1'b1;
        end
      end
    end
  end

  wire [127:0] res_out = res_sign?(~res[127:0] + 128'b1):res[127:0];
  assign res_hi = res_out[127:64];
  assign res_lo[63:32] = res_w?{32{res_out[31]}}:res_out[63:32];
  assign res_lo[31:0]  = res_out[31:0];
  
endmodule
